﻿/******************************************************************************
 *
 * @copyright:          Copyright 2011 UniSky Ltd.
 * @file:
 * @author:              kenping.liu
 * @creation:
 * @description:
 *
 * @modifications
 * date         user                description
 *
 *
 * @more-details
 *
 *****************************************************************************/
#ifndef _UNISKY_SYS_H_
#define _UNISKY_SYS_H_

#include "../u_inc.h"

U_NAMESPACE_BEGIN(u)
U_NAMESPACE_BEGIN(sys)

class OS
{
public:
    static int set_coredump_path(const char *path);
};

class Lock
{
public:
    Lock(const char* name=NULL);
    ~Lock();

    bool lock();
    bool try_lock();
    bool unlock();

private:
#if defined(WINDOWS)
    HANDLE          _mtx;
#else
    pthread_mutex_t _mtx;
#endif
};

class AutoLock
{
public:
    AutoLock(Lock* lck);
    ~AutoLock();
private:
    Lock* _lck;
};

class Event
{
public:
    Event();
    ~Event();
    bool set();
    bool reset();
#if defined(WINDOWS)
    DWORD wait(DWORD mills=INFINITE);
#else
    DWORD wait(DWORD mills=0);
#endif

private:
#if defined(WINDOWS)
    HANDLE _evt;
#endif
};

class Semaphore
{
public:
    Semaphore(const char* name=NULL);
    ~Semaphore();
    bool create();
    void destroy();
    void wait();
private:
#if defined(WINDOWS)
    char   _name[128];
    HANDLE _semaphore;
#endif
};

///////////////////////////////////////////////////////////////////////////////
class Thread
{
public:
    typedef void (* Routine)(void* param);

#if defined(WINDOWS)
    Thread(const char* name, bool auto_del=false);
    ~Thread();
    static DWORD WINAPI thread_proc(LPVOID param);
#else
    Thread(const char* name, bool auto_del=false);
    virtual ~Thread();
    static void* thread_proc(void* param);
#endif

    void begin();
    void tryterminate();
    void terminate();
    void suspend();
    void resume();
    void wait(UINT mills=0);
    bool running() { return _running; }
    UINT tid() { return _tid; }
    char* thread_name() { return _name; }

protected:
    virtual void run() = 0;

	void Delay(int mseconds);
	void WakeUp();

    UINT  _tid;
#if defined (WINDOWS)
    HANDLE    _thread;
#else
    pthread_t _thread;
#endif

    bool      _running;
    bool      _auto_del;
    char      _name[128];
    Event     _event;

    pthread_mutex_t m_mutex;
    pthread_cond_t m_cond;
};

template <typename T>
class TaskDoerT : public Thread
{
public:
    typedef void (T::*WorkMethod)(void* param);
    typedef void (*WorkFunction)(void* param);

    TaskDoerT(T* obj, WorkMethod method, void* param=NULL)
        : Thread("TaskDoer<>", true), _func(NULL)
    {
        _obj       = obj;
        _method    = method;
        _user_obj  = param;
    };

    TaskDoerT(WorkFunction func, void* param=NULL)
        : Thread("TaskDoer", true), _obj(NULL), _method(NULL)
    {
        _func     = func;
        _user_obj = param;
    };

    ~TaskDoerT()
    {
        //Thread::~Thread();
    };

    void work()
    {
        begin();
    }

protected:
    virtual void run()
    {
        if ( NULL!=_obj )
        {
            (_obj->*_method)(_user_obj);
        }
        else if ( NULL!=_func )
        {
            (_func)(_user_obj);
        }
    }

private:
    T*           _obj;
    WorkMethod   _method;
    WorkFunction _func;
    void*        _user_obj;
};

struct FakeTask
{
    void execute(void* param){};
};

typedef TaskDoerT<FakeTask> TaskDoer;

U_NAMESPACE_END(sys)
U_NAMESPACE_END(u)


#endif
